package com.example.gmranqi.common.codeGenerator;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.Data;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * mybatis-generator 代码生成工具
 */
@Data
public class CodeGenerator {
    private String PARENT_NAME = "com.surfilter.demo.service";
    private String PARENT_PATH = "";
    private String MODULAR_NAME = "";
    private String SRC_MAIN_JAVA = "src/main/java/";
    private String AUTHOR = "zongHui Gao";
    private boolean REST_CONTROLLER_STYLE = true;
    private String JDBC_MYSQL_URL = "jdbc:mysql://10.10.160.47:3306/oormp_1124?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull";
    private String JDBC_DRIVER_NAME = "com.mysql.jdbc.Driver";
    private String JDBC_USERNAME = "root";
    private String JDBC_PASSWORD = "surfilter1218";
    private boolean swagger2 = false;
    private String MAVEN_PATH = "";

    public CodeGenerator() {

    }

    public CodeGenerator(String PARENT_NAME, String MODULAR_NAME, String SRC_MAIN_JAVA, String AUTHOR, boolean REST_CONTROLLER_STYLE, String JDBC_MYSQL_URL, String JDBC_DRIVER_NAME, String JDBC_USERNAME, String JDBC_PASSWORD, boolean swagger2, String MAVEN_PATH) {
        this.PARENT_NAME = PARENT_NAME;
        this.MODULAR_NAME = MODULAR_NAME;
        this.SRC_MAIN_JAVA = SRC_MAIN_JAVA;
        this.AUTHOR = AUTHOR;
        this.REST_CONTROLLER_STYLE = REST_CONTROLLER_STYLE;
        this.JDBC_MYSQL_URL = JDBC_MYSQL_URL;
        this.JDBC_DRIVER_NAME = JDBC_DRIVER_NAME;
        this.JDBC_USERNAME = JDBC_USERNAME;
        this.JDBC_PASSWORD = JDBC_PASSWORD;
        this.swagger2 = swagger2;
        this.MAVEN_PATH = MAVEN_PATH;
        if (PARENT_NAME != null) {
            this.PARENT_PATH = PARENT_NAME.replaceAll("\\.", "/");
        }
    }

    public CodeGenerator(String PARENT_NAME, String MODULAR_NAME, String SRC_MAIN_JAVA, String AUTHOR, boolean REST_CONTROLLER_STYLE, String JDBC_MYSQL_URL, String JDBC_DRIVER_NAME, String JDBC_USERNAME, String JDBC_PASSWORD) {
        this.PARENT_NAME = PARENT_NAME;
        this.MODULAR_NAME = MODULAR_NAME;
        this.SRC_MAIN_JAVA = SRC_MAIN_JAVA;
        this.AUTHOR = AUTHOR;
        this.REST_CONTROLLER_STYLE = REST_CONTROLLER_STYLE;
        this.JDBC_MYSQL_URL = JDBC_MYSQL_URL;
        this.JDBC_DRIVER_NAME = JDBC_DRIVER_NAME;
        this.JDBC_USERNAME = JDBC_USERNAME;
        this.JDBC_PASSWORD = JDBC_PASSWORD;
        this.swagger2 = true;
        if (PARENT_NAME != null) {
            this.PARENT_PATH = PARENT_NAME.replaceAll("\\.", "/");
        }
    }

    public void autoGenerator(String moduleName, String tableName, String tablePrefix) {
        new AutoGenerator()
                .setGlobalConfig(this.getGlobalConfig())
                .setDataSource(this.getDataSourceConfig())
                .setPackageInfo(this.getPackageConfig(moduleName))
                .setStrategy(this.getStrategyConfig(tableName, tablePrefix))
                .setCfg(this.getInjectionConfig(moduleName))
                .setTemplate(this.getTemplateConfig())
                .execute();
    }

    private static String getDateTime() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    private  InjectionConfig getInjectionConfig(final String moduleName) {
        return new InjectionConfig() {
            @Override
            public void initMap() {
                Map map = new HashMap();
                map.put("dateTime", getDateTime());
//                map.put("dtoPath", joinPackage(moduleName, "dto"));
                map.put("dtoPath", moduleName);
                ConfigBuilder configBuilder = this.getConfig();
                setMap(map);
                final String projectPath = System.getProperty("user.dir") + MODULAR_NAME;
                List<FileOutConfig> fileOutConfigList = new ArrayList<FileOutConfig>();
                // 自定义配置会被优先输出
                fileOutConfigList.add(new FileOutConfig("/templates/generator/mapper.xml.vm") {
                    @Override
                    public String outputFile(TableInfo tableInfo) {
                        // 自定义输出文件名，如果entity设置了前后缀，此次注意xml的名称也会跟着发生变化
//                        return projectPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
                        return projectPath + "/src/main/java/com/surfilter/oormp/common/codeGenerator/code/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
                    }
                });
                fileOutConfigList.add(new FileOutConfig("/templates/generator/entityvo.java.vm") {
                    @Override
                    public String outputFile(TableInfo tableInfo) {
                        // 自定义输出文件名，如果entity设置了前后缀，此次注意xml的名称也会跟着发生变化
//                        return projectPath + "/src/main/java/" + getPARENT_PATH() + "/" + moduleName +"/entity/" + tableInfo.getEntityName() + "VO" + StringPool.DOT_JAVA;
                        return projectPath + "/src/main/java/com/surfilter/oormp/common/codeGenerator/code/" +"/entity/" + tableInfo.getEntityName() + "VO" + StringPool.DOT_JAVA;
                    }
                });
                fileOutConfigList.add(new FileOutConfig("/templates/generator/entityquery.java.vm") {
                    @Override
                    public String outputFile(TableInfo tableInfo) {
                        // 自定义输出文件名，如果entity设置了前后缀，此次注意xml的名称也会跟着发生变化
//                        return projectPath + "/src/main/java/" + getPARENT_PATH() + "/" + moduleName +"/entity/" + tableInfo.getEntityName() + "Query" + StringPool.DOT_JAVA;
                        return projectPath + "/src/main/java/com/surfilter/oormp/common/codeGenerator/code/" +"/entity/" + tableInfo.getEntityName() + "Query" + StringPool.DOT_JAVA;
                    }
                });
                setFileOutConfigList(fileOutConfigList);
            }
        };
    }


    private StrategyConfig getStrategyConfig(String tableName, String tablePrefix) {
        return new StrategyConfig()
                .setNaming(NamingStrategy.underline_to_camel)
                .setColumnNaming(NamingStrategy.underline_to_camel)
                .setInclude(tableName)
                .setRestControllerStyle(REST_CONTROLLER_STYLE)
                .setEntityBuilderModel(false)
                .setEntityLombokModel(true)
                .setSuperEntityClass("com.surfilter.oormp.entity.mysql.BaseEntity")
                .setSuperMapperClass("com.baomidou.mybatisplus.core.mapper.BaseMapper")
//                .setSuperServiceClass("com.surfilter.central.common.db.mybatis.dao.MybatisBaseDao")
//                .setSuperServiceImplClass("com.surfilter.central.common.db.mybatis.dao.impl.MybatisBaseDaoImpl")
                .setControllerMappingHyphenStyle(true)
                .entityTableFieldAnnotationEnable(true)
                .setTablePrefix(tablePrefix + "_");
    }

//    生成代码的路径配置
    private PackageConfig getPackageConfig(String moduleName) {
        PackageConfig packageConfig = new PackageConfig()
                .setModuleName(moduleName)
                .setParent(PARENT_NAME)
                .setController("controller")
                .setService("service")
                .setServiceImpl("service.impl")
                .setMapper("dao")
                .setXml("dao")
                .setEntity("entity");
//

        return packageConfig;
    }

    private DataSourceConfig getDataSourceConfig() {
        return new DataSourceConfig()
                .setUrl(JDBC_MYSQL_URL)
                .setDriverName(JDBC_DRIVER_NAME)
                .setUsername(JDBC_USERNAME)
                .setPassword(JDBC_PASSWORD);
    }

    private GlobalConfig getGlobalConfig() {
        String projectPath = System.getProperty("user.dir") + MAVEN_PATH;
        String filePath = projectPath + "/" + MODULAR_NAME + SRC_MAIN_JAVA;
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            filePath = filePath.replaceAll("/+|\\\\+", "\\\\");
        } else {
            filePath = filePath.replaceAll("/+|\\\\+", "/");

        }
        return new GlobalConfig()
                .setOutputDir(filePath)
//                .setIdType(IdType.AUTO)
                .setAuthor(AUTHOR)
                .setBaseColumnList(true)
                .setEnableCache(false)
                .setServiceName("%sService")
//                .setServiceImplName("%sDaoImpl")
                .setBaseResultMap(true)
                .setFileOverride(true)
                .setSwagger2(swagger2)
                .setOpen(false)
                .setMapperName("%sDao")
//                控制时间字段为Date类型
                .setDateType(DateType.ONLY_DATE);
    }

    private TemplateConfig getTemplateConfig() {
        return new TemplateConfig()
                .setController("/templates/generator/controller.java.vm")
                .setService("/templates/generator/service.java.vm")
                .setServiceImpl("/templates/generator/serviceImpl.java.vm")
                .setEntity("/templates/generator/entity.java.vm")
                .setMapper("/templates/generator/dao.java.vm")
                .setXml("/templates/generator/mapper.xml.vm")
                // 关闭默认 xml 生成，调整生成 至 根目录
                .setXml(null);
    }

    private String joinPackage(String parent, String subPackage) {
        return StringUtils.isEmpty(parent) ? subPackage : getPARENT_NAME() + "." + parent + "." + subPackage;
    }
}